class Product < ActiveRecord::Base
  after_initialize :init

  has_and_belongs_to_many :categories, :join_table => "product_has_categories"
  has_and_belongs_to_many :parameters, :join_table => "product_has_parameters"

  has_many :relations, :as => :relatable, :dependent => :destroy

  has_many :photos, :as => :viewable, :order => :position, :dependent => :destroy
  has_many :attachments, :as => :viewable, :order => :position, :dependent => :destroy

  has_many :comments, :foreign_key => :commentable_id

  has_many :variants, :conditions => ["product_variants.is_master = ?", false]
  has_many :variants_with_master, :class_name => "Variant", :dependent => :destroy
  has_one  :master, :class_name => "Variant", :conditions => ["product_variants.is_master = ?", true]

  has_one  :product_shipping_method
  has_one  :shipping_method, :through => :product_shipping_method
  
  has_one  :product_has_prototype
  has_one  :prototype, :through => :product_has_prototype

  has_many :supplements, :as => :viewable, :order => :position, :dependent => :destroy

  has_one  :property_group, :as => :viewable
  has_many :properties, :through => :property_group, :order => :position

  belongs_to :tax_category
  belongs_to :amount_type

  delegate :tax,  :to => "tax_category"
  delegate :name, :to => "amount_type", :prefix => true

  delegate :number, :number=, :price, :price=, :is_master, :is_master=, :to => "master"

  accepts_nested_attributes_for :photos
  accepts_nested_attributes_for :property_group, :allow_destroy => true
  accepts_nested_attributes_for :parameters, :limit => 4
  accepts_nested_attributes_for :product_shipping_method, :allow_destroy => true, :reject_if => proc {|attr| attr['shipping_method_id'].blank?}
  accepts_nested_attributes_for :comments, :allow_destroy => true, :reject_if => proc {|attr| attr['comment'].blank?}

  acts_as_commentable
  
  has_paper_trail
  diff :exclude => [:id, :created_at, :updated_at]

  validates :presentation, :price, :number, :url, :tax_category, :amount_type, :title, :presence => true
  validates :url, :uniqueness => true, :format => {:with => Format::URL_REGEX}, :length => {:maximum => 70}
  validates :presentation, :number, :length => {:maximum => 70}
  validates :state, :inclusion => {:in => ["on_sale", "not_on_sale", "hidden", "deleted"]}
  validates :price, :numericality => {:greater_than => 0}
  validates :number, :format => {:with => Format::STRING_REGEX}
  validate :date_check

  def init
    self.on_sale_to   = I18n.l(self.on_sale_to)   unless self.on_sale_to.blank?
    self.on_sale_from = I18n.l(self.on_sale_from) unless self.on_sale_from.blank?
  end

    def relation_types
    RelationType.find_all_by_applies_to(self.to_s, :order => :name)
  end

  def accessories
    relations.map(&:related_to).select {|product| product.deleted_at.nil?}
  end

  def self.on_sale
    where(["products.state NOT IN ('hidden')"])
  end
  
  private
  def date_check
    unless on_sale_to.blank? || on_sale_from.blank?
      errors.add(:base, I18n.t("errors.custom.messages.on_sale_to_greater_than")) if on_sale_to < on_sale_from
    end
  end

  alias new_master master
  def master
    new_master || build_master
  end

  alias new_product_shipping_method product_shipping_method
  def product_shipping_method
    new_product_shipping_method || build_product_shipping_method
  end
end
